angular.module('dataDisplay', ['ui.grid', 'ui.select', 'ui.grid.edit', 'common', 'ui.grid.pagination', 'ui.grid.resizeColumns', 'ui.grid.moveColumns', 'toastr'])
    .controller('dataDisplayController',
    ['$scope', '$http', 'toastr','commonService',
        function ($scope, $http, toastr, service) {

            $scope.data = [];
            $scope.columnOptions = [];

            $scope.paginationOptions = {
                pageNumber: 1,
                pageSize: 20
            };

            $scope.gridOption = {
                enableVerticalScrollbar: 0,
                enableColumnResizing: true,
                enableSelectAll: true,
                exporterOlderExcelCompatibility: true,
                exporterCsvFilename: 'ExceptionReport.csv',
                enablePaging: true,

                paginationPageSizes: [20, 50, 100],
                paginationPageSize: 20,
                useExternalPagination: true,
                paginationTemplate: '/views/gridPagination.html',
                enableGridMenu: false,
                enableRowSelection: true,
                excessRows: 1000,
                columnDefs: $scope.columnOptions,
                data: $scope.data
            };
            $scope.dataKey = $("input[type='hidden']").attr("id");

            $scope.modifiedCache = {};

            $scope.gridOption.onRegisterApi = function (gridApi) {
                $scope.gridApi = gridApi;
                gridApi.pagination.on.paginationChanged($scope, function (newPage, pageSize) {
                    $scope.gridOption.pageNumber = newPage;
                    $scope.gridOption.pageSize = pageSize;

                    $.get("/collection/" + $scope.dataKey,
                        {where: $scope.generateCriteria(), option: {page: [newPage, pageSize]}},
                        function (data) {
                            if (data.data instanceof Array) {
                                $scope.gridOption.data = [];
                                $scope.$digest();
                                $scope.gridOption.data = data.data;
                                $scope.gridOption.totalItems = data.count;
                                $scope.$digest();
                                //service.updateDatePicker(data.data);
                                if (data.data.length == 0) {
                                    toastr.success("未查询到数据!");
                                }
                            } else {
                                if(data.data instanceof Object)
                                    toastr.error(data.data.description);
                                else
                                    toastr.error("查询错误! "+ data.data);
                            }
                        }
                    );
                });
            };


            $.post('/displayData/' + $scope.dataKey, {}, function (data) {
                $.each(data.columns, function (obj) {
                    if (data.columns[obj].isDisplay) {
                        var temp = {
                            field: data.columns[obj].columnName,
                            name: data.columns[obj].displayName,
                            enableColumnMenu: false
                        };
                        if (data.columns[obj].editable) {
                            switch (data.columns[obj].dataType) {

                                case 'date':
                                    if(data.columns[obj].filter){
                                        var formatTemp = data.columns[obj].filter.replace(/y+/gi,"Y").replace(/m+/g,"i")
                                            .replace(/M+/g,"m").replace(/d+/g,"d").replace(/h+/g,"H");
                                    }
                                    temp.cellTemplate = '<datetimepicker dateID="{{row.entity.$$hashKey}}'+temp.field+'" ' +
                                    'ng-model="MODEL_COL_FIELD" ng-change="col.colDef.onChange(row)" name="' + temp.field + '" ' +
                                    'format="'+formatTemp+'" class="form-control" style="background-color:transparent" />';
                                    break;
                                case 'string':
                                    temp.cellTemplate = '<input ng-model="MODEL_COL_FIELD" class="form-control" style="background-color:transparent;border-radius:3px" ' +
                                        'ng-change="col.colDef.onChange(row)" name="' + temp.field + '" />';
                                    break;
                                case 'array':
                                    temp.cellTemplate = '<input ng-model="MODEL_COL_FIELD" ' +
                                        'ng-change="col.colDef.onChange(row)" name="' + temp.field + '" />';

                                    break;
                                case 'function':
                                    temp.cellTemplate = '<input ng-model="MODEL_COL_FIELD" ' +
                                        'ng-change="col.colDef.onChange(row)" name="' + temp.field + '" />';

                                    break;
                                // default means object type, select item
                                default:
                                    var tempArray = [];
                                    for (var op in data.columns[obj].dataType.options) {
                                        if(op.trim().length != 0)
                                            tempArray.push({id: op, value: data.columns[obj].dataType.options[op]});
                                    }
                                    temp.editDropdownRowEntityOptionsArray = tempArray;
                                    var isMuilt = data.columns[obj].dataType.setting.multi ? "multiple" : "";
                                    temp.cellTemplate =
                                        '<ui-select ng-model="MODEL_COL_FIELD" on-select="col.colDef.onSelect(row)" append-to-body="true" ' + isMuilt + '>' +
                                        '<ui-select-match>{{ $select.selected.value }}</ui-select-match>' +
                                        '<ui-select-choices repeat="item.id as item in col.colDef.editDropdownRowEntityOptionsArray">' +
                                        '<div>{{ item.value }}</div>' +
                                        '</ui-select-choices>' +
                                        '</ui-select>';
                                    temp.onSelect = function (row) {
                                        $scope.modifiedCache[row.entity.$$hashKey] = row.entity;
                                    };
                                    break;
                            }
                            temp.onChange = function (row) {
                                $scope.modifiedCache[row.entity.$$hashKey] = row.entity;
                            };

                        } else {
                            if (data.columns[obj].extra) {
                                temp.cellTemplate = '<div style="width: 100%">' +
                                '<span class="glyphicon glyphicon-plus-sign extra-row" onmouseover="changeMinus(this)" onmouseout="changePlus(this)" ng-click="col.colDef.onExtra(row,MODEL_COL_FIELD)"></span>'+
                                '<span style="position: relative;top:3px">{{MODEL_COL_FIELD.substring(0,' + parseInt(data.columns[obj].extra) + ')}}...</span></div>';

                                //
                                temp.onExtra = function (row, allData) {
                                    $scope.extraModal(this.name, allData);
                                }
                            } else {
                                temp.cellTemplate = '<span>{{MODEL_COL_FIELD}}</span>';
                            }
                        }
                        if (data.columns[obj].width) temp.width = data.columns[obj].width;
                        $scope.columnOptions.push(temp);
                    }
                });

                $scope.extraModal = function (title,value) {
                    $("#extraModalTitle").html(title);
                    $("#extraModalBody").html('<pre>'+service.htmlencode(value)+'</pre>');
                    $("#extraModal").modal();
                };

                $scope.search = function () {

                    $.get("/collection/" + data._id,
                        {where: $scope.generateCriteria(), option: {page: [1, 20]}},
                        function (data) {
                            if (data.data instanceof Array) {
                                $scope.gridOption.data = [];
                                $scope.$digest();
                                $scope.gridOption.totalItems = data.count;
                                $scope.gridOption.pageNumber = 1;
                                $scope.gridOption.paginationCurrentPage = 1;
                                $scope.gridOption.data = data.data;
                                $scope.$digest();

                                if (data.data.length == 0) {
                                    toastr.success("未查询到数据!");
                                }
                            } else {
                                if(data.data instanceof Object)
                                    toastr.error(data.data.description);
                                else
                                    toastr.error("查询错误! "+ data.data);
                            }
                        }
                    );
                };

                $scope.generateCriteria = function () {
                    var criteria = {};
                    $.each(data.columns, function (col) {
                        if (data.columns[col].searchable) {
                            var fieldVal = null;
                            var fieldType = data.columns[col].dataType;
                            var colName = data.columns[col].columnName;
                            if (fieldType == 'date') {
                                var dateFrom = $("#" + data.columns[col].columnName + "From").val();
                                var dateTo = $("#" + data.columns[col].columnName + "To").val();
                                criteria[colName] = {};
                                if (dateFrom.length != 0) criteria[colName].$gt = new Date(dateFrom).getTime();
                                if (dateTo.length != 0) criteria[colName].$lt = new Date(dateTo).getTime();
                            } else if (fieldType instanceof Object) {
                                fieldVal = $("#" + data.columns[col].columnName).val();
                                if (fieldType.multiSelect) {
                                    //todo append $or options to $and property
                                    if (fieldVal.length != 0)
                                        criteria[colName] = fieldVal;
                                } else {
                                    if (fieldVal.length != 0)
                                        criteria[colName] = fieldVal;
                                }
                            } else {
                                fieldVal = $("#" + data.columns[col].columnName).val().replace(/\s+/, "");
                                if (fieldType == 'array') {
                                    if (fieldVal.split(/[，|,|；|;]/).length != 0) {
                                        var optionsObj = [];
                                        var tempArray = fieldVal.split(/[，|,|；|;]/);
                                        for (var i = 0; i < tempArray.length; i++) {
                                            if (tempArray[i].trim().length != 0) {
                                                var tempObj = {};
                                                tempObj[colName] = tempArray[i];
                                                optionsObj.push(tempObj);
                                            }
                                        }
                                        if (!criteria.$and) {
                                            criteria.$and = [];
                                        }
                                        if (optionsObj.length != 0)
                                            criteria.$and.push({$or: JSON.stringify(optionsObj)});
                                    }
                                } else {
                                    if (fieldVal.length != 0)
                                        criteria[colName] = fieldVal;
                                }
                            }
                        }
                    });
                    return criteria;
                }

                $scope.save = function () {
                    var sendData = [];
                    for (var i in $scope.modifiedCache) {
                        sendData.push({where: $scope.modifiedCache[i]._id, update: $scope.modifiedCache[i]})
                    }

                    if(sendData.length == 0) {
                        toastr.success("未修改任何行! ");
                        return;
                    }
                    $scope.modifiedCache = {};
                    $http({
                        method: 'PUT',
                        url: '/collection/' + data._id,
                        data: {data: sendData}
                    }).then(function (result) {
                        if (result.data == 'success') {
                            toastr.success("保存成功! ");
                        } else {
                            if(result.data instanceof Object)
                                toastr.error(result.data.description);
                            else
                                toastr.error("查询错误! "+ result.data);
                        }
                    });
                };

                $scope.export = function () {
                    var queryObj = {};
                    var temp = $scope.generateCriteria();
                    for (var i in temp) {
                        if (temp[i] && temp[i].length != 0) {
                            if (temp[i] instanceof Object) {
                                var hasProperty = false;
                                for (var j in temp[i]) {
                                    hasProperty = true;
                                    break;
                                }
                                hasProperty && (queryObj[i] = temp[i]);
                            } else {
                                queryObj[i] = temp[i];
                            }
                        }
                    }
                    window.open("/download/" + data._id + "?query=" + JSON.stringify(queryObj));
                    window.close();
                }
            });

            $scope.showTimePicker = function(id) {
                $("#"+id).datetimepicker();
            };
        }
    ]);